/**
 * @file image_saver.c
 * @brief 图像保存模块实现
 * @version 1.0
 * @date 2023-05-20
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "image_saver.h"
#include "system_utils.h"

// 图像保存模块全局状态
static struct {
    bool initialized;           // 是否初始化
    ImageSaverConfig config;    // 配置
    int frame_count;            // 帧计数器
    char save_path[MAX_PATH_LENGTH]; // 完整保存路径
    time_t start_time;          // 开始时间
} g_image_saver = {0};

// 内部函数前向声明
static void generate_filename(char *filename, size_t size, const char *type);

int init_image_saver(ImageSaverConfig *config) {
    if (!config) {
        log_message(LOG_LEVEL_ERROR, "图像保存: 无效的配置参数");
        return -1;
    }
    
    // 复制配置
    memcpy(&g_image_saver.config, config, sizeof(ImageSaverConfig));
    
    // 初始化状态
    g_image_saver.initialized = true;
    g_image_saver.frame_count = 0;
    g_image_saver.start_time = time(NULL);
    
    // 确保保存目录存在
    if (g_image_saver.config.enabled) {
        if (create_save_directory() != 0) {
            log_message(LOG_LEVEL_ERROR, "图像保存: 创建保存目录失败");
            return -1;
        }
    }
    
    log_message(LOG_LEVEL_INFO, "图像保存: 初始化成功%s", 
               g_image_saver.config.enabled ? "" : " (已禁用)");
    
    return 0;
}

int save_image(const Image *image, const char *type) {
    if (!g_image_saver.initialized || !g_image_saver.config.enabled) {
        return -1;
    }
    
    if (!image || !image->data || !type) {
        log_message(LOG_LEVEL_ERROR, "图像保存: 无效的参数");
        return -1;
    }
    
    // 生成文件名
    char filename[MAX_PATH_LENGTH];
    generate_filename(filename, sizeof(filename), type);
    
    // 使用OpenCV保存图像
#ifdef HAVE_OPENCV
    bool success = opencv_save_image(image->data, image->width, image->height, 
                                    image->channels, filename, g_image_saver.config.jpg_quality);
    
    if (success) {
        log_message(LOG_LEVEL_DEBUG, "图像保存: 成功保存图像 %s", filename);
        return 0;
    } else {
        log_message(LOG_LEVEL_ERROR, "图像保存: 保存图像失败 %s", filename);
        return -1;
    }
#else
    log_message(LOG_LEVEL_ERROR, "图像保存: 未启用OpenCV支持，无法保存图像");
    return -1;
#endif
}

int save_raw_image(const unsigned char *image_data, int width, int height, int channels, const char *type) {
    if (!g_image_saver.initialized || !g_image_saver.config.enabled) {
        return -1;
    }
    
    if (!image_data || width <= 0 || height <= 0 || channels <= 0 || !type) {
        log_message(LOG_LEVEL_ERROR, "图像保存: 无效的参数");
        return -1;
    }
    
    // 生成文件名
    char filename[MAX_PATH_LENGTH];
    generate_filename(filename, sizeof(filename), type);
    
    // 使用OpenCV保存图像
#ifdef HAVE_OPENCV
    bool success = opencv_save_image(image_data, width, height, channels, 
                                    filename, g_image_saver.config.jpg_quality);
    
    if (success) {
        log_message(LOG_LEVEL_DEBUG, "图像保存: 成功保存原始图像 %s", filename);
        return 0;
    } else {
        log_message(LOG_LEVEL_ERROR, "图像保存: 保存原始图像失败 %s", filename);
        return -1;
    }
#else
    log_message(LOG_LEVEL_ERROR, "图像保存: 未启用OpenCV支持，无法保存图像");
    return -1;
#endif
}

bool should_save_image(void) {
    if (!g_image_saver.initialized || !g_image_saver.config.enabled) {
        return false;
    }
    
    // 根据保存间隔决定是否应该保存当前帧
    return (g_image_saver.frame_count % g_image_saver.config.save_interval) == 0;
}

void update_frame_counter(void) {
    if (g_image_saver.initialized) {
        g_image_saver.frame_count++;
    }
}

int create_save_directory(void) {
    // 初始检查
    if (!g_image_saver.initialized) {
        log_message(LOG_LEVEL_ERROR, "图像保存: 模块未初始化");
        return -1;
    }
    
    // 首先确保主保存目录存在
    if (create_directory(g_image_saver.config.save_dir) != 0) {
        log_message(LOG_LEVEL_ERROR, "图像保存: 创建主保存目录失败: %s", g_image_saver.config.save_dir);
        return -1;
    }
    
    // 创建时间戳子目录
    char timestamp[32] = "";
    time_t now = time(NULL);
    struct tm tm_info;
    
#ifdef _WIN32
    localtime_s(&tm_info, &now);
#else
    localtime_r(&now, &tm_info);
#endif
    
    strftime(timestamp, sizeof(timestamp), "%Y%m%d_%H%M%S", &tm_info);
    
    // 检查字符串长度，防止缓冲区溢出
    size_t dir_len = strlen(g_image_saver.config.save_dir);
    size_t timestamp_len = strlen(timestamp);
    size_t required_len = dir_len + 9 + timestamp_len; // 9是"/images_"的长度
    
    if (required_len >= sizeof(g_image_saver.save_path)) {
        log_message(LOG_LEVEL_ERROR, "图像保存: 保存路径过长，需要%zu字节，最大%zu字节", 
                  required_len, sizeof(g_image_saver.save_path) - 1);
        return -1;
    }
    
    // 分步构建完整路径以避免可能的缓冲区溢出
    size_t offset = 0;
    size_t max_size = sizeof(g_image_saver.save_path);
    
    // 1. 复制基础路径
    offset += snprintf(g_image_saver.save_path, max_size, "%s", g_image_saver.config.save_dir);
    
    // 2. 添加目录分隔符和前缀
    offset += snprintf(g_image_saver.save_path + offset, max_size - offset, "/images_");
    
    // 3. 添加时间戳
    snprintf(g_image_saver.save_path + offset, max_size - offset, "%s", timestamp);
    
    // 创建目录
    if (create_directory(g_image_saver.save_path) != 0) {
        log_message(LOG_LEVEL_ERROR, "图像保存: 创建时间戳子目录失败: %s", g_image_saver.save_path);
        return -1;
    }
    
    log_message(LOG_LEVEL_INFO, "图像保存: 创建保存目录: %s", g_image_saver.save_path);
    return 0;
}

void cleanup_image_saver(void) {
    if (g_image_saver.initialized) {
        g_image_saver.initialized = false;
        log_message(LOG_LEVEL_INFO, "图像保存: 资源已清理");
    }
}

// 生成带时间戳的文件名
static void generate_filename(char *filename, size_t size, const char *type) {
    char timestamp[32] = "";
    
    // 如果需要添加时间戳
    if (g_image_saver.config.append_timestamp) {
        time_t now = time(NULL);
        struct tm tm_info;
        
#ifdef _WIN32
        localtime_s(&tm_info, &now);
#else
        localtime_r(&now, &tm_info);
#endif
        
        strftime(timestamp, sizeof(timestamp), "_%Y%m%d_%H%M%S", &tm_info);
    }
    
    // 检查各字符串长度，防止缓冲区溢出
    size_t prefix_len = strlen(g_image_saver.config.prefix);
    size_t type_len = strlen(type);
    size_t timestamp_len = strlen(timestamp);
    size_t path_len = strlen(g_image_saver.save_path);
    
    // 计算所需总长度（包括分隔符和数字部分）
    size_t required_len = path_len + 1 + prefix_len + 1 + type_len + timestamp_len + 8 + 5; // 加上"/"、"_"和".jpg"以及数字部分
    
    if (required_len >= size) {
        // 缓冲区不足，采取安全措施
        if (size > 0) {
            filename[0] = '\0'; // 确保返回空字符串而不是未初始化的字符串
        }
        log_message(LOG_LEVEL_ERROR, "图像保存: 生成文件名所需缓冲区过小，需要%zu字节", required_len);
        return;
    }
    
    // 分步构建文件名以避免可能的缓冲区溢出
    size_t offset = 0;
    
    // 1. 复制保存路径
    offset += snprintf(filename + offset, size - offset, "%s/", g_image_saver.save_path);
    
    // 2. 添加文件名前缀和类型
    offset += snprintf(filename + offset, size - offset, "%s_%s", 
                     g_image_saver.config.prefix, type);
    
    // 3. 添加时间戳（如果有）
    if (timestamp[0] != '\0') {
        offset += snprintf(filename + offset, size - offset, "%s", timestamp);
    }
    
    // 4. 添加帧号和扩展名
    snprintf(filename + offset, size - offset, "_%06d.jpg", g_image_saver.frame_count);
} 